package com.zx.sdk.league.member;

import android.app.Activity;
import android.content.Context;
import android.view.ViewGroup;

import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.qq.e.ads.banner2.UnifiedBannerADListener;
import com.qq.e.ads.banner2.UnifiedBannerView;
import com.qq.e.ads.rewardvideo.RewardVideoAD;
import com.qq.e.ads.rewardvideo.RewardVideoADListener;
import com.qq.e.ads.rewardvideo.ServerSideVerificationOptions;
import com.qq.e.ads.splash.SplashAD;
import com.qq.e.ads.splash.SplashADListener;
import com.qq.e.comm.constants.BiddingLossReason;
import com.qq.e.comm.managers.GDTAdSdk;
import com.qq.e.comm.managers.setting.GlobalSetting;
import com.qq.e.comm.pi.IBidding;
import com.qq.e.comm.util.AdError;
import com.zx.sdk.ZxSDK;
import com.zx.sdk.listener.BaseZxBannerListener;
import com.zx.sdk.listener.BaseZxRewardListener;
import com.zx.sdk.listener.BaseZxSplashListener;
import com.zx.sdk.model.AdInfo;
import com.zx.sdk.model.ReadyAdPosition;
import com.zx.sdk.model.ZxError;
import com.zx.sdk.util.LogHelper;

import java.util.HashMap;
import java.util.Map;

public class QQ extends BaseLeagueMember<SplashAD, RewardVideoAD, UnifiedBannerView, Object, Object> {
    @Override
    public String getName() {
        return "qq";
    }

    @Override
    protected void onInit(Context context, String appId, boolean initialized) {
        if ("1021".equals(ZxSDK.getAppId())) {// 如果是铜梁龙则打开这个配置，用于测试
            GlobalSetting.setEnableCollectAppInstallStatus(true);
        }
        GDTAdSdk.init(context, appId);
    }

    @Override
    protected void onLoadSplash(AdInfo adInfo, ViewGroup container, String mode, String type, BaseZxSplashListener listener) {
        SplashAD[] splashContainer = new SplashAD[1];
        SplashAD splashAD = new SplashAD(context, adInfo.getMapPid(), new SplashADListener() {
            @Override
            public void onADClicked() {
                listener.onADClicked(QQ.this, adInfo);
            }

            @Override
            public void onADDismissed() {
                listener.onADDismissed(QQ.this, adInfo);
            }

            @Override
            public void onADExposure() {
                listener.onADExposure(QQ.this, adInfo);
            }

            @Override
            public void onADLoaded(long l) {
                saveSplash(adInfo.getMapPid(), splashContainer[0], container);
                if (ZxSDK.FETCH_AND_SHOW.equals(mode)) {
                    if (!showSplash(adInfo, container, listener)) {
                        listener.onNoAD(QQ.this, new ZxError("-1", "广告显示失败"), adInfo);
                        return;
                    }
                }
                listener.onADLoaded(QQ.this, l, adInfo);
            }

            @Override
            public void onADPresent() {
                listener.onADPresent(QQ.this, adInfo);
            }

            @Override
            public void onADTick(long l) {
                listener.onADTick(QQ.this, l, adInfo);
            }

            @Override
            public void onNoAD(AdError error) {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        listener.onPreLoadNoAD(QQ.this, new ZxError(String.valueOf(error.getErrorCode()), error.getErrorMsg()), adInfo);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        listener.onNoAD(QQ.this, new ZxError(String.valueOf(error.getErrorCode()), error.getErrorMsg()), adInfo);
                        break;
                }
                if (splashContainer[0] != null && ZxSDK.Bidding.equals(type)) {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put(IBidding.LOSS_REASON, BiddingLossReason.NO_AD);
                    map.put(IBidding.ADN_ID, "2");
                    sendLossNotification(adInfo.getMapPid(), splashContainer[0], map);
                }
            }
        }, 5000);
        splashContainer[0] = splashAD;
        splashAD.fetchAdOnly();
    }

    @Override
    public boolean onShowSplash(AdInfo adInfo, ViewGroup container, @Nullable SplashAD splash, BaseZxSplashListener listener) {
        if (splash == null) return false;
        splash.showAd(container);
        return true;
    }

    @Override
    public void onLoadReward(Activity context, AdInfo adInfo, String mode, String type, BaseZxRewardListener listener) {
        final RewardVideoAD[] rewardContainer = new RewardVideoAD[1];
        final RewardVideoAD rewardVideoAD = new RewardVideoAD(context, adInfo.getMapPid(), new RewardVideoADListener() {
            @Override
            public void onADClick() {
                listener.onADClick(QQ.this, adInfo);
            }

            @Override
            public void onADClose() {
                listener.onADClose(QQ.this, adInfo);
            }

            @Override
            public void onADExpose() {
                listener.onADExpose(QQ.this, adInfo);
            }

            @Override
            public void onADLoad() {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        saveReward(adInfo.getMapPid(), rewardContainer[0]);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        rewardContainer[0].showAD();
                        break;
                }
                listener.onADLoad(QQ.this, adInfo);
            }

            @Override
            public void onADShow() {
                listener.onADExpose(QQ.this, adInfo);
            }

            @Override
            public void onError(AdError adError) {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        listener.onPreLoadADError(QQ.this, new ZxError(String.valueOf(adError.getErrorCode()), adError.getErrorMsg()), adInfo);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        listener.onNoAD(QQ.this, new ZxError(String.valueOf(adError.getErrorCode()), adError.getErrorMsg()), adInfo);
                        break;
                }
                if (rewardContainer[0] != null && ZxSDK.Bidding.equals(type)) {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put(IBidding.LOSS_REASON, BiddingLossReason.NO_AD);
                    map.put(IBidding.ADN_ID, "2");
                    sendLossNotification(adInfo.getMapPid(), rewardContainer[0], map);
                }
            }

            @Override
            public void onReward(Map<String, Object> map) {
                listener.onReward(QQ.this, map, adInfo);
                GDTAdSdk.getGDTAdManger().showOpenOrInstallAppDialog(buttonType ->
                        LogHelper.d("qq ad showOpenOrInstallAppDialog onButtonClick:" + buttonType));
            }

            @Override
            public void onVideoCached() {
                listener.onVideoCached(QQ.this, adInfo);
            }

            @Override
            public void onVideoComplete() {
                listener.onVideoComplete(QQ.this, adInfo);
            }
        }, true);

        rewardContainer[0] = rewardVideoAD;
        rewardVideoAD.setServerSideVerificationOptions(new ServerSideVerificationOptions.Builder()
                .setUserId(ZxSDK.getUid())
                .setCustomData(new Gson().toJson(adInfo))
                .build());
        rewardVideoAD.loadAD();
    }

    @Override
    public boolean onShowReward(Activity context, AdInfo adInfo, @Nullable RewardVideoAD reward, BaseZxRewardListener listener) {
        if (reward == null) return false;
        reward.showAD();
        return true;
    }

    @Override
    public void onLoadInterstitial(Activity context, AdInfo adInfo, String mode, String type, BaseZxRewardListener listener) {

    }

    @Override
    public boolean onShowInterstitial(Activity context, AdInfo adInfo, @Nullable Object interstitial, BaseZxRewardListener listener) {
        return false;
    }

    @Override
    public boolean isPreResReady(String type, String pid) {
        if (type.equals(ZxSDK.REWARD)) {
            RewardVideoAD rewardVideoAD = getFilledRewardByPid(pid);
            if (rewardVideoAD == null) {
                return false;
            }
            if (!rewardVideoAD.isValid()) {
                LogHelper.d("【联盟=" + getName() + "】" + "预加载的Reward广告已经过期，所以失效 appId = " + this.mobAppId + " pid =" + pid);
                return false;
            }
            if (rewardVideoAD.hasShown()) {
                LogHelper.d("【联盟=" + getName() + "】" + "预加载的Reward广告已经显示，所以失效 appId = " + this.mobAppId + " pid =" + pid);
                return false;
            }
            return true;
        }
        return super.isPreResReady(type, pid);
    }


    /**
     * 获取 cpm 单位=分
     *
     * @return -1=为加载到资源
     */
    @Override
    public int getCpmByPid(String type, String pid) {
        int def = super.getCpmByPid(type, pid);
        switch (type) {
            case ZxSDK.SPLASH:
                def = splashMap.get(pid) == null ? def : splashMap.get(pid).getECPM();
            case ZxSDK.REWARD:
                def = rewardMap.get(pid) == null ? def : rewardMap.get(pid).getECPM();
            case ZxSDK.BANNER:
                def = bannerMap.get(pid) == null ? def : bannerMap.get(pid).getECPM();
        }
        cpmCache.put(type + pid, def);
        return def;
    }

    @Override
    public void notifyBiddingWin(String type, String mapPid, @Nullable ReadyAdPosition loser) {
        IBidding iBidding = getIBidding(type, mapPid);
        if (iBidding == null) {
            return;
        }
        HashMap<String, Object> map = new HashMap<>();
        // 键 IBidding.EXPECT_COST_PRICE 对应值为竞胜出价
        map.put(IBidding.EXPECT_COST_PRICE, getCpmByPid(type, mapPid));
        // 键 IBidding.HIGHEST_LOSS_PRICE 对应值为最大竞败方出价
        if (loser != null) {
            map.put(IBidding.HIGHEST_LOSS_PRICE, loser.getCpm());
        }
        iBidding.sendWinNotification(map);
        LogHelper.d(getName(), "notifyBiddingWin", mapPid, map.toString());
    }

    @Override
    public void notifyBiddingLose(String type, String mapPid, ReadyAdPosition winner, ZxSDK.LoseReason reason) {
        IBidding iBidding = getIBidding(type, mapPid);
        if (iBidding == null) {
            return;
        }
        HashMap<String, Object> map = new HashMap<>();
        // 键 IBidding.WIN_PRICE 对应值为竞胜出价
        map.put(IBidding.WIN_PRICE, winner.getCpm());
        // 键 IBidding.LOSS_REASON 值为优量汇广告竞败原因，必填
        map.put(IBidding.LOSS_REASON, getLoseReason(reason));
        // 键 IBidding.ADN_ID 值为本次竞胜方渠道ID，必填
        //        对于【adnID】字段回传支持3个枚举值，分别代表：
        //        1 - 输给优量汇其它广告，当优量汇目标价报价为本次竞价的最高报价时，可上报此值，仅对混合比价类型的开发者适用
        //        2 - 输给第三方ADN，当其它ADN报价为本次竞价的最高报价时，可上报此值，您无需回传具体竞胜方渠道；
        //        3 - 输给自售广告主，当自售广告源报价为本次竞价的最高报价时，可上报此值，仅对有自售广告源的开发者使用；
        map.put(IBidding.ADN_ID, getName().equalsIgnoreCase(winner.getLeague()) ? "1" : "2");
        sendLossNotification(mapPid, iBidding, map);
    }

    private void sendLossNotification(String pid, IBidding iBidding, HashMap<String, Object> map) {
        iBidding.sendLossNotification(map);
        LogHelper.d(getName(), "notifyBiddingLose", pid, map.toString());
    }

    @Nullable
    private IBidding getIBidding(String type, String pid) {
        IBidding iBidding = null;
        if (ZxSDK.REWARD.equals(type)) {
            iBidding = rewardMap.get(pid);
        } else if (ZxSDK.SPLASH.equals(type)) {
            iBidding = splashMap.get(pid);
        }
        return iBidding;
    }

    protected int getLoseReason(ZxSDK.LoseReason reason) {
        return BiddingLossReason.LOW_PRICE;
    }

    @Override
    public void onLoadBanner(Activity context, ViewGroup container, AdInfo adInfo, String mode, String type, BaseZxBannerListener listener) {
        UnifiedBannerView[] mUnifiedBannerView = new UnifiedBannerView[1];
        mUnifiedBannerView[0] = new UnifiedBannerView(context, adInfo.getMapPid(), new UnifiedBannerADListener() {
            @Override
            public void onADClicked() {
                listener.onAdClick(null, QQ.this, adInfo);
            }

            @Override
            public void onADClosed() {
                listener.onAdClose(null, QQ.this, adInfo);
                dismissBanner(container, mUnifiedBannerView[0]);
            }

            @Override
            public void onADExposure() {
                listener.onAdShow(null, QQ.this, adInfo);
            }

            @Override
            public void onADLeftApplication() {

            }

            @Override
            public void onADReceive() {
                switch (mode) {
                    case ZxSDK.FETCH_ONLY:
                        saveBanner(adInfo.getMapPid(), mUnifiedBannerView[0]);
                        break;
                    case ZxSDK.FETCH_AND_SHOW:
                        onShowBanner(context, adInfo, container, mUnifiedBannerView[0], listener);
                        break;
                }
            }

            @Override
            public void onNoAD(AdError adError) {
                listener.onAdFailed(new ZxError(adError.getErrorCode() + "", adError.getErrorMsg()), QQ.this, adInfo);
            }
        });
        mUnifiedBannerView[0].loadAD();
    }

    @Override
    public boolean onShowBanner(Activity activity, AdInfo adInfo, ViewGroup container, UnifiedBannerView banner, BaseZxBannerListener listener) {
        container.removeAllViews();
        container.addView(banner);
        addCloseBtnToBanner(container, () -> dismissBanner(container, banner));
        return true;
    }

    private void dismissBanner(ViewGroup container, UnifiedBannerView mUnifiedBannerView) {
        container.removeAllViews();
        if (mUnifiedBannerView != null) {
            mUnifiedBannerView.destroy();
        }
    }

    @Override
    protected void onDestroyBanner(UnifiedBannerView banner) {
        banner.destroy();
    }
}